<template>
  <el-dialog
    title="API测试"
    v-model="dialogVisible"
    width="900px"
    destroy-on-close
    @close="handleClose"
    :modal="true"
    :append-to-body="true"
    :lock-scroll="true"
    class="api-test-dialog"
  >
    <div class="api-test-container">
      <!-- API信息展示 -->
      <el-card class="api-info-card" shadow="never">
        <template #header>
          <div class="card-header">
            <el-icon><InfoFilled /></el-icon>
            <span>API信息</span>
          </div>
        </template>
        <div class="api-info">
          <div class="info-item">
            <span class="label">API名称：</span>
            <span class="value">{{ apiConfig?.function_name }}</span>
          </div>
          <div class="info-item">
            <span class="label">请求方法：</span>
            <el-tag
              :type="getMethodType(apiConfig?.http_method)"
              size="small"
            >
              {{ apiConfig?.http_method }}
            </el-tag>
          </div>
          <div class="info-item">
            <span class="label">接口地址：</span>
            <span class="value">{{ apiConfig?.endpoint_url }}</span>
          </div>
          <div class="info-item">
            <span class="label">描述：</span>
            <span class="value">{{ apiConfig?.description || '无' }}</span>
          </div>
        </div>
      </el-card>

      <!-- 参数配置 -->
      <el-card class="params-card" shadow="never">
        <template #header>
          <div class="card-header">
            <el-icon><Setting /></el-icon>
            <span>测试参数</span>
          </div>
        </template>
        
        <div v-if="requiredParams.length > 0" class="params-section">
          <h4>必需参数</h4>
          <el-form :model="testParams" label-width="120px">
            <el-form-item
              v-for="param in requiredParams"
              :key="param"
              :label="param"
              :required="true"
            >
              <el-input
                v-model="testParams[param]"
                :placeholder="`请输入${param}`"
              />
            </el-form-item>
          </el-form>
        </div>
        
        <div class="params-section">
          <h4>自定义参数</h4>
          <div class="custom-params">
            <div
              v-for="(param, index) in customParams"
              :key="index"
              class="param-item"
            >
              <el-input
                v-model="param.key"
                placeholder="参数名"
                style="width: 200px; margin-right: 10px"
              />
              <el-input
                v-model="param.value"
                placeholder="参数值"
                style="width: 200px; margin-right: 10px"
              />
              <el-button
                type="danger"
                size="small"
                @click="removeCustomParam(index)"
              >
                删除
              </el-button>
            </div>
            <el-button
              type="primary"
              size="small"
              @click="addCustomParam"
            >
              <el-icon><Plus /></el-icon>
              添加参数
            </el-button>
          </div>
        </div>
      </el-card>

      <!-- 测试结果 -->
      <el-card class="result-card" shadow="never">
        <template #header>
          <div class="card-header">
            <el-icon><Monitor /></el-icon>
            <span>测试结果</span>
            <div class="header-actions">
              <el-button
                type="primary"
                :loading="testing"
                @click="handleTest"
              >
                <el-icon><CaretRight /></el-icon>
                {{ testing ? '测试中...' : '开始测试' }}
              </el-button>
            </div>
          </div>
        </template>
        
        <div v-if="!testResult && !testing" class="no-result">
          <el-empty description="点击开始测试按钮执行API测试" />
        </div>
        
        <div v-if="testing" class="testing-status">
          <el-icon class="loading-icon"><Loading /></el-icon>
          <span>正在测试API连接...</span>
        </div>
        
        <div v-if="testResult" class="test-result">
          <!-- 请求信息 -->
          <div class="result-section">
            <h4>请求信息</h4>
            <div class="request-info">
              <div class="info-row">
                <span class="label">请求URL：</span>
                <span class="value">{{ testResult.request?.url }}</span>
              </div>
              <div class="info-row">
                <span class="label">请求方法：</span>
                <span class="value">{{ testResult.request?.method }}</span>
              </div>
              <div class="info-row">
                <span class="label">请求时间：</span>
                <span class="value">{{ formatDate(testResult.timestamp) }}</span>
              </div>
              <div class="info-row">
                <span class="label">响应时间：</span>
                <span class="value">{{ testResult.duration }}ms</span>
              </div>
            </div>
          </div>
          
          <!-- 响应状态 -->
          <div class="result-section">
            <h4>响应状态</h4>
            <div class="status-info">
              <el-tag
                :type="getStatusType(testResult.status_code)"
                size="large"
              >
                {{ testResult.status_code }} {{ testResult.status_text }}
              </el-tag>
              <span class="success-indicator" v-if="testResult.success">
                <el-icon color="#67c23a"><SuccessFilled /></el-icon>
                测试成功
              </span>
              <span class="error-indicator" v-else>
                <el-icon color="#f56c6c"><CircleCloseFilled /></el-icon>
                测试失败
              </span>
            </div>
          </div>
          
          <!-- 响应数据 -->
          <div class="result-section">
            <h4>响应数据</h4>
            <el-tabs v-model="activeTab" type="border-card">
              <el-tab-pane label="格式化" name="formatted">
                <pre class="response-data formatted">{{ formatJson(testResult.response_data) }}</pre>
              </el-tab-pane>
              <el-tab-pane label="原始数据" name="raw">
                <pre class="response-data raw">{{ testResult.response_data }}</pre>
              </el-tab-pane>
            </el-tabs>
          </div>
          
          <!-- 错误信息 -->
          <div v-if="testResult.error" class="result-section">
            <h4>错误信息</h4>
            <div class="error-info">
              <el-alert
                :title="testResult.error"
                type="error"
                :closable="false"
                show-icon
              />
            </div>
          </div>
        </div>
      </el-card>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleClose">关闭</el-button>
        <el-button
          type="primary"
          :loading="testing"
          @click="handleTest"
        >
          重新测试
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, reactive, computed, watch } from 'vue'
import {
  InfoFilled,
  Setting,
  Monitor,
  CaretRight,
  Loading,
  Plus,
  SuccessFilled,
  CircleCloseFilled,
} from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { testApiFunction } from '@/api/external-api'

// 定义组件名
defineOptions({
  name: 'ApiTest',
})

// Props
const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false,
  },
  apiConfig: {
    type: Object,
    default: () => ({}),
  },
})

// Emits
const emit = defineEmits(['update:modelValue'])

// 状态
const testing = ref(false)
const testResult = ref(null)
const activeTab = ref('formatted')
const testParams = reactive({})
const customParams = ref([{ key: '', value: '' }])

// 对话框显示状态
const dialogVisible = computed({
  get: () => props.modelValue,
  set: (value) => emit('update:modelValue', value),
})

// 必需参数
const requiredParams = computed(() => {
  return props.apiConfig?.required_params || []
})

// 监听API配置变化，初始化参数
watch(
  () => props.apiConfig,
  (newConfig) => {
    if (newConfig) {
      // 清空之前的参数
      Object.keys(testParams).forEach(key => {
        delete testParams[key]
      })
      
      // 初始化必需参数
      if (newConfig.required_params) {
        newConfig.required_params.forEach(param => {
          testParams[param] = ''
        })
      }
      
      // 重置测试结果
      testResult.value = null
    }
  },
  { immediate: true }
)

// 获取请求方法标签类型
const getMethodType = (method) => {
  const typeMap = {
    GET: 'success',
    POST: 'primary',
    PUT: 'warning',
    DELETE: 'danger',
    PATCH: 'info',
  }
  return typeMap[method] || 'info'
}

// 获取状态码标签类型
const getStatusType = (statusCode) => {
  if (statusCode >= 200 && statusCode < 300) {
    return 'success'
  } else if (statusCode >= 400 && statusCode < 500) {
    return 'warning'
  } else if (statusCode >= 500) {
    return 'danger'
  }
  return 'info'
}

// 格式化日期
const formatDate = (dateString) => {
  if (!dateString) return '-'
  return new Date(dateString).toLocaleString('zh-CN')
}

// 格式化JSON
const formatJson = (data) => {
  try {
    if (typeof data === 'string') {
      return JSON.stringify(JSON.parse(data), null, 2)
    }
    return JSON.stringify(data, null, 2)
  } catch (error) {
    return data
  }
}

// 添加自定义参数
const addCustomParam = () => {
  customParams.value.push({ key: '', value: '' })
}

// 删除自定义参数
const removeCustomParam = (index) => {
  if (customParams.value.length > 1) {
    customParams.value.splice(index, 1)
  }
}

// 构建测试参数
const buildTestParams = () => {
  const params = { ...testParams }
  
  // 添加自定义参数
  customParams.value.forEach(param => {
    if (param.key && param.value) {
      params[param.key] = param.value
    }
  })
  
  return params
}

// 验证必需参数
const validateRequiredParams = () => {
  for (const param of requiredParams.value) {
    if (!testParams[param] || testParams[param].trim() === '') {
      ElMessage.error(`请填写必需参数：${param}`)
      return false
    }
  }
  return true
}

// 执行API测试
const handleTest = async () => {
  if (!validateRequiredParams()) {
    return
  }
  
  testing.value = true
  testResult.value = null
  const startTime = Date.now()

  try {
    
    // 构建测试参数
    const params = buildTestParams()
    
    // 调用真实的API测试接口
    const response = await testApiFunction(props.apiConfig.id, params)
    
    const endTime = Date.now()
    const duration = endTime - startTime
    
    testResult.value = {
      success: true,
      status_code: response.status || 200,
      status_text: response.statusText || 'OK',
      duration,
      timestamp: new Date().toISOString(),
      request: {
        url: props.apiConfig.endpoint_url,
        method: props.apiConfig.http_method,
        params,
      },
      response_data: response.data,
      error: null,
    }
    
    ElMessage.success('API测试成功')
  } catch (error) {
    console.error('API测试失败:', error)
    const endTime = Date.now()
    const duration = endTime - startTime
    
    testResult.value = {
      success: false,
      status_code: error.response?.status || 0,
      status_text: error.response?.statusText || 'Network Error',
      duration,
      timestamp: new Date().toISOString(),
      request: {
        url: props.apiConfig.endpoint_url,
        method: props.apiConfig.http_method,
        params: buildTestParams(),
      },
      response_data: error.response?.data || null,
      error: error.response?.data?.message || error.message || '网络错误或服务器无响应',
    }
    ElMessage.error('API测试失败: ' + (error.response?.data?.message || error.message || '未知错误'))
  } finally {
    testing.value = false
  }
}

// 关闭对话框
const handleClose = () => {
  dialogVisible.value = false
  testResult.value = null
  Object.keys(testParams).forEach(key => {
    testParams[key] = ''
  })
  customParams.value = [{ key: '', value: '' }]
}
</script>

<style scoped>
.api-test-dialog {
  z-index: 9999;
}

.api-test-dialog :deep(.el-dialog) {
  margin: 5vh auto;
  max-height: 90vh;
  overflow-y: auto;
}

.api-test-dialog :deep(.el-overlay) {
  background-color: rgba(0, 0, 0, 0.5);
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 9998;
}

.api-test-dialog :deep(.el-dialog__body) {
  max-height: 70vh;
  overflow-y: auto;
  padding: 20px;
}

.api-test-container {
  max-height: 70vh;
  overflow-y: auto;
}

.api-info-card,
.params-card,
.result-card {
  margin-bottom: 20px;
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: 600;
}

.card-header .el-icon {
  margin-right: 8px;
  color: #409eff;
}

.api-info {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 15px;
}

.info-item {
  display: flex;
  align-items: center;
}

.info-item .label {
  font-weight: 500;
  color: #606266;
  margin-right: 8px;
  min-width: 80px;
}

.info-item .value {
  color: #303133;
  word-break: break-all;
}

.params-section {
  margin-bottom: 20px;
}

.params-section h4 {
  margin: 0 0 15px 0;
  color: #303133;
  font-size: 14px;
  font-weight: 600;
}

.custom-params {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  padding: 15px;
  background-color: #fafafa;
}

.param-item {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
}

.param-item:last-of-type {
  margin-bottom: 15px;
}

.no-result {
  text-align: center;
  padding: 40px 0;
}

.testing-status {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 0;
  color: #409eff;
}

.loading-icon {
  margin-right: 8px;
  animation: rotate 2s linear infinite;
}

@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.test-result {
  padding: 20px 0;
}

.result-section {
  margin-bottom: 25px;
}

.result-section h4 {
  margin: 0 0 15px 0;
  color: #303133;
  font-size: 16px;
  font-weight: 600;
  border-bottom: 2px solid #e4e7ed;
  padding-bottom: 8px;
}

.request-info {
  background-color: #f8f9fa;
  border-radius: 4px;
  padding: 15px;
}

.info-row {
  display: flex;
  margin-bottom: 8px;
}

.info-row:last-child {
  margin-bottom: 0;
}

.info-row .label {
  font-weight: 500;
  color: #606266;
  min-width: 100px;
}

.info-row .value {
  color: #303133;
  word-break: break-all;
}

.status-info {
  display: flex;
  align-items: center;
  gap: 15px;
}

.success-indicator,
.error-indicator {
  display: flex;
  align-items: center;
  gap: 5px;
  font-weight: 500;
}

.success-indicator {
  color: #67c23a;
}

.error-indicator {
  color: #f56c6c;
}

.response-data {
  background-color: #f8f9fa;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  padding: 15px;
  margin: 0;
  font-family: 'Courier New', monospace;
  font-size: 12px;
  line-height: 1.5;
  max-height: 300px;
  overflow-y: auto;
  white-space: pre-wrap;
  word-break: break-all;
}

.response-data.formatted {
  color: #2c3e50;
}

.response-data.raw {
  color: #7f8c8d;
}

.error-info {
  margin-top: 10px;
}

.dialog-footer {
  text-align: right;
}

:deep(.el-card__header) {
  padding: 15px 20px;
  background-color: #f8f9fa;
  border-bottom: 1px solid #e4e7ed;
}

:deep(.el-card__body) {
  padding: 20px;
}

:deep(.el-tabs__content) {
  padding: 0;
}
</style>